"""
五子棋规则层
负责游戏规则、棋盘状态管理
"""

from .forbidden_rules import ForbiddenRules


class GobangRules:
    """五子棋规则类"""
    
    def __init__(self, board_size=15, enable_forbidden=True):
        """
        初始化棋盘
        :param board_size: 棋盘大小，默认15x15
        :param enable_forbidden: 是否启用禁手规则（仅对黑棋有效）
        """
        self.board_size = board_size
        self.board = [[0 for _ in range(board_size)] for _ in range(board_size)]
        self.current_player = 1  # 1为黑棋，2为白棋
        self.game_over = False
        self.winner = None
        self.move_history = []  # 记录落子历史
        self.enable_forbidden = enable_forbidden  # 禁手规则
        self.forbidden_reason = None  # 禁手原因
        
    def reset(self):
        """重置棋盘"""
        self.board = [[0 for _ in range(self.board_size)] for _ in range(self.board_size)]
        self.current_player = 1
        self.game_over = False
        self.winner = None
        self.move_history = []
        self.forbidden_reason = None
        
    def is_valid_move(self, row, col):
        """
        检查落子是否合法
        :param row: 行坐标
        :param col: 列坐标
        :return: 是否合法
        """
        if self.game_over:
            return False
        if row < 0 or row >= self.board_size or col < 0 or col >= self.board_size:
            return False
        if self.board[row][col] != 0:
            return False
        return True
    
    def make_move(self, row, col):
        """
        落子
        :param row: 行坐标
        :param col: 列坐标
        :return: 是否成功落子
        """
        if not self.is_valid_move(row, col):
            return False
        
        self.board[row][col] = self.current_player
        self.move_history.append((row, col, self.current_player))
        
        # 检查黑棋是否触发禁手（仅针对黑棋）
        if self.enable_forbidden and self.current_player == 1:
            forbidden_type = self.check_forbidden(row, col)
            if forbidden_type:
                self.game_over = True
                self.winner = 2  # 黑棋禁手，白棋获胜
                self.forbidden_reason = forbidden_type
                return True
        
        # 检查是否获胜
        if self.check_winner(row, col):
            self.game_over = True
            self.winner = self.current_player
        else:
            # 检查是否平局（棋盘已满）
            if self.is_board_full():
                self.game_over = True
                self.winner = 0  # 0表示平局
            else:
                # 切换玩家
                self.current_player = 3 - self.current_player  # 1->2, 2->1
        
        return True
    
    def undo_move(self):
        """悔棋，撤销上一步"""
        if not self.move_history:
            return False
        
        row, col, player = self.move_history.pop()
        self.board[row][col] = 0
        self.current_player = player
        self.game_over = False
        self.winner = None
        return True
    
    def check_winner(self, row, col):
        """
        检查当前落子是否获胜（形成五子连珠）
        :param row: 最后落子的行坐标
        :param col: 最后落子的列坐标
        :return: 是否获胜
        """
        player = self.board[row][col]
        
        # 四个方向：横、竖、左斜、右斜
        directions = [
            [(0, 1), (0, -1)],   # 横向
            [(1, 0), (-1, 0)],   # 纵向
            [(1, 1), (-1, -1)],  # 左上到右下
            [(1, -1), (-1, 1)]   # 右上到左下
        ]
        
        for direction in directions:
            count = 1  # 包括当前落子
            
            # 检查两个方向
            for dx, dy in direction:
                x, y = row + dx, col + dy
                while 0 <= x < self.board_size and 0 <= y < self.board_size:
                    if self.board[x][y] == player:
                        count += 1
                        x += dx
                        y += dy
                    else:
                        break
            
            # 五子连珠获胜（不考虑长连）
            if count == 5:
                return True
        
        return False
    
    def check_forbidden(self, row, col):
        """
        检查黑棋是否触发禁手
        :param row: 落子的行坐标
        :param col: 落子的列坐标
        :return: 禁手类型字符串，或None
        """
        player = self.board[row][col]
        return ForbiddenRules.check_forbidden(self.board, self.board_size, row, col, player)
    
    def is_board_full(self):
        """检查棋盘是否已满"""
        for row in self.board:
            if 0 in row:
                return False
        return True
    
    def get_valid_moves(self):
        """
        获取所有合法落子位置
        :return: 合法位置列表 [(row, col), ...]
        """
        valid_moves = []
        for row in range(self.board_size):
            for col in range(self.board_size):
                if self.board[row][col] == 0:
                    valid_moves.append((row, col))
        return valid_moves
    
    def get_board_state(self):
        """
        获取当前棋盘状态
        :return: 棋盘二维数组的副本
        """
        return [row[:] for row in self.board]
    
    def print_board(self):
        """打印棋盘（用于调试）"""
        print("  ", end="")
        for i in range(self.board_size):
            print(f"{i:2}", end=" ")
        print()
        
        for i, row in enumerate(self.board):
            print(f"{i:2}", end=" ")
            for cell in row:
                if cell == 0:
                    print(" .", end=" ")
                elif cell == 1:
                    print(" ●", end=" ")  # 黑棋
                else:
                    print(" ○", end=" ")  # 白棋
            print()
